import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
import _createClass from "@babel/runtime/helpers/esm/createClass";
import _assertThisInitialized from "@babel/runtime/helpers/esm/assertThisInitialized";
import _inherits from "@babel/runtime/helpers/esm/inherits";
import _createSuper from "@babel/runtime/helpers/esm/createSuper";
import _isFunction from "lodash/isFunction";

/**
 * createDropField
 * @date 2019/1/4
 */
import React from 'react';
import { DropTarget } from 'react-dnd';
import { DragType, emptyFieldType } from "../../config";
import styles from "../index.less?modules";
/**
 * 创建 DropField
 *
 * @param {{
 *  dropAcceptTypes: string|string[],
 *  canDrop: (props: object, monitor: object) => boolean,
 *  drop: Function,
 * }} [{
 *   dropAcceptTypes = [DragType.dragField, DragType.drawDragField],
 *   canDrop = defaultCanDrop,
 *   drop = defaultDrop,
 * }={}]
 * @param {string|string[]} [dropAcceptTypes=[DragType.dragField, DragType.drawDragField]] - 接收的 drop 类型
 * @param {(props: object, monitor: object) => boolean} [canDrop=defaultCanDrop] - 是否可以 drop
 * @param {Function} [drop=defaultDrop] - drop 触发的方法
 */

export default function createDropField() {
  var _dec, _class;

  var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
      _ref$dropAcceptTypes = _ref.dropAcceptTypes,
      dropAcceptTypes = _ref$dropAcceptTypes === void 0 ? [DragType.dragField, DragType.drawDragField] : _ref$dropAcceptTypes,
      _ref$canDrop = _ref.canDrop,
      canDrop = _ref$canDrop === void 0 ? defaultCanDrop : _ref$canDrop,
      _ref$drop = _ref.drop,
      drop = _ref$drop === void 0 ? defaultDrop : _ref$drop;

  var dropFieldSpec = {
    drop: drop,
    canDrop: canDrop
  };

  var dropFieldCollect = function dropFieldCollect(connect, monitor) {
    var connectDropTarget = connect.dropTarget();
    var isOverAndCanDrop = monitor.isOver() && monitor.canDrop();
    return {
      connectDropTarget: connectDropTarget,
      isOverAndCanDrop: isOverAndCanDrop
    };
  };

  var DropField = (_dec = DropTarget(dropAcceptTypes, dropFieldSpec, dropFieldCollect), _dec(_class = /*#__PURE__*/function (_React$Component) {
    _inherits(DropField, _React$Component);

    var _super = _createSuper(DropField);

    function DropField(props) {
      var _this;

      _classCallCheck(this, DropField);

      _this = _super.call(this, props);
      _this.handleFieldClick = _this.handleFieldClick.bind(_assertThisInitialized(_this));
      return _this;
    }

    _createClass(DropField, [{
      key: "handleFieldClick",
      value: function handleFieldClick(e) {
        // 阻止冒泡
        e.stopPropagation();
        var _this$props = this.props,
            onActiveField = _this$props.onActiveField,
            component = _this$props.component,
            pComponent = _this$props.pComponent;

        if (onActiveField) {
          onActiveField(pComponent, component);
        }
      }
    }, {
      key: "render",
      value: function render() {
        var _this$props2 = this.props,
            connectDropTarget = _this$props2.connectDropTarget,
            children = _this$props2.children,
            isOverAndCanDrop = _this$props2.isOverAndCanDrop,
            currentEditField = _this$props2.currentEditField,
            component = _this$props2.component;
        var isActiveField = currentEditField === component;
        var isEmptyField = component.componentType === emptyFieldType;
        var dropFieldClassName = [styles['drop-field']];

        if (isOverAndCanDrop) {
          dropFieldClassName.push(styles['drop-field-over']);
        }

        if (isEmptyField) {
          dropFieldClassName.push(styles['drop-field-placeholder']);
        }

        if (isActiveField) {
          dropFieldClassName.push(styles['drop-field-active']);
        }

        return connectDropTarget && connectDropTarget( /*#__PURE__*/React.createElement("div", {
          className: dropFieldClassName.join(' '),
          onClick: this.handleFieldClick
        }, React.cloneElement(children, {
          isOverAndCanDrop: isOverAndCanDrop
        })));
      }
    }]);

    return DropField;
  }(React.Component)) || _class);
  return DropField;
}

function defaultCanDrop(props, monitor) {
  var _monitor$getItem = monitor.getItem(),
      drawPComponent = _monitor$getItem.pComponent;

  var dropPComponent = props.pComponent,
      component = props.component;
  var dragType = monitor.getItemType();

  if (dragType === DragType.dragField) {
    // 新增只能替换空的 field
    if (component.componentType === emptyFieldType) {
      return true;
    }
  } else if (dragType === DragType.drawDragField) {
    // 只能交换同一个 component 里面的 field
    if (drawPComponent === dropPComponent) {
      return true;
    }
  }

  return false;
}

function defaultDrop(props, monitor) {
  var _monitor$getItem2 = monitor.getItem(),
      dragField = _monitor$getItem2.component,
      drawPComponent = _monitor$getItem2.pComponent,
      dragFieldOptions = _monitor$getItem2.fieldOptions;

  var dropField = props.component,
      pComponent = props.pComponent,
      dropFieldOptions = props.fieldOptions;
  var dragType = monitor.getItemType();

  if (dragType === DragType.drawDragField) {
    // 交换位置, 已经由 canDrop 保证 只能是同一个 pComponent
    var onSwapField = props.onSwapField;

    if (drawPComponent === pComponent && _isFunction(onSwapField)) {
      onSwapField(pComponent, dragField, dropField, dragFieldOptions, dropFieldOptions);
    }
  } else if (dragType === DragType.dragField) {
    var onAddField = props.onAddField;

    if (_isFunction(onAddField)) {
      onAddField(pComponent, dragField, dropField, dragFieldOptions, dropFieldOptions);
    }
  }
}